package main.java.game;

import main.java.game.combatant.Hero;
import main.java.game.combatant.Monster;
import main.java.game.command.AttackHero;
import main.java.game.command.BattleCommand;
import main.java.game.item.equipableTreasure.SpecialObject;

/**
 * @author alumno
 */
public class Battle {
	/**
	 * @uml.property name="userInterface"
	 * @uml.associationEnd
	 */

	public Battle(Game game, Monster monster, Player player, Hero hero) {
		this.player = player;
		this.setMonster(monster);
		this.hero=hero;
		this.game = game;

		this.startTurn();
	}

	/**
	 * @uml.property name="monster"
	 * @uml.associationEnd
	 */
	private Hero hero;
	private Game game;

	/**
	 * Getter of the property <tt>monster</tt>
	 * 
	 * @return Returns the monster.
	 * @uml.property name="monster"
	 */
	public Hero getHero() {
		return hero;
	}

	/**
	 * Setter of the property <tt>monster</tt>
	 * 
	 * @param monster
	 *            The monster to set.
	 * @uml.property name="monster"
	 */
	public void setHero(Hero hero) {
		this.hero = hero;
	}

	/**
	 * @uml.property name="monster1"
	 * @uml.associationEnd
	 */
	private Monster monster;

	/**
	 * Getter of the property <tt>monster1</tt>
	 * 
	 * @return Returns the monster1.
	 * @uml.property name="monster1"
	 */
	public Monster getMonster() {
		return monster;
	}

	/**
	 * Setter of the property <tt>monster1</tt>
	 * 
	 * @param monster1
	 *            The monster1 to set.
	 * @uml.property name="monster1"
	 */
	public void setMonster(Monster monster) {
		this.monster = monster;
	}

	/**
	 * @uml.property name="player"
	 * @uml.associationEnd
	 */
	private Player player;

	/**
	 * Getter of the property <tt>player</tt>
	 * 
	 * @return Returns the player.
	 * @uml.property name="player"
	 */
	public Player getPlayer() {
		return player;
	}

	/**
	 * Setter of the property <tt>player</tt>
	 * 
	 * @param player
	 *            The player to set.
	 * @uml.property name="player"
	 */
	public void setPlayer(Player player) {
		this.player = player;
	}

	/**
	 * @uml.property name="isHeroeTurn"
	 */
	private boolean isHeroeTurn=true;

	/**
	 * Getter of the property <tt>isHeroeTurn</tt>
	 * 
	 * @return Returns the isHeroeTurn.
	 * @uml.property name="isHeroeTurn"
	 */
	public boolean getIsHeroeTurn() {
		return isHeroeTurn;
	}

	/**
	 * Setter of the property <tt>isHeroeTurn</tt>
	 * 
	 * @param isHeroeTurn
	 *            The isHeroeTurn to set.
	 * @uml.property name="isHeroeTurn"
	 */
	public void changeIsHeroTurn() {
		if (isHeroeTurn) {
			this.isHeroeTurn = false;
		} else {
			this.isHeroeTurn = true;
		}
	}

	public void fight() {
		for(SpecialObject equip:hero.getSpecialObjects()){
			equip.useSpecialHability(this);
		}
		while ((!isDefeatedMonster() && !playerDefeated()) && !isCancelledBattle()) {
			this.turnAssignement();
		}
		
	}


	/**
	 * Getter of the property <tt>defeatedMonster</tt>
	 * 
	 * @return Returns the defeatedMonster.
	 * @uml.property name="defeatedMonster"
	 */
	public Boolean isDefeatedMonster() {
		return this.getMonster().getLifepoints() == 0;
	}

	public void chooseHero() {
		
		this.setHero(UserInterface.selectHero(player));
	}

	public void heroTurn() {
		System.out.println("Hero turn");
		BattleCommand bc = UserInterface.battleInterface(this,game);
		bc.execute();
		if(isCancelledBattle()){
			System.out.println("You withdrew from battle and it cost you "+this.getMonster().getWithdrawalPrice()+" gold coins");
		}
		if(isDefeatedMonster()){
			System.out.println("Monster defeated");
			monsterDefeated();
		}
	}

	public void monsterTurn() {

		System.out.println("Monster turn");
		BattleCommand bc = new AttackHero(this);
		bc.execute();
		if (isHeroDefeated()){
			System.out.println("Hero defeated");
			heroDefeated();
		}
	}

	public void monsterDefeated() {
		player.getDeadMonsters().add(this.getMonster());
		System.out.println("Battle win");
		String message =finishedBattle();
		rewardObtained(message);
		
	}

	private void rewardObtained(String message) {
		player.setGold(player.getGold()+monster.getReward());
		System.out.println(message+"\n"+"You won: "+monster.getReward()+" gold coins!!");
		
	}

	public void heroDefeated() {
		player.getHeroes().remove(this.getHero());
		for(SpecialObject equip:hero.getSpecialObjects()){
			equip.stopUsingSpecialHability(this);
		}
		if (player.isHerosEmpty()){
			String message =finishedBattle();
			System.out.println(message);
		}else{
			chooseHero();
			for(SpecialObject equip:hero.getSpecialObjects()){
				equip.useSpecialHability(this);
			}
		}
	}

	public boolean isHeroDefeated() {
		return getHero().getLifepoints() == 0;
	}

	public boolean playerDefeated() {
		boolean losed = false;
		losed = this.getPlayer().getHeroes().isEmpty();
		return losed;
	}

	public void startTurn() {
		Integer initial = this.compareInit();
		if (initial < 0)
			changeIsHeroTurn();

	}

	public Integer compareInit() {
		Integer heroInit = hero.getInit();
		Integer monsterInit = monster.getInit();
		return heroInit.compareTo(monsterInit);
	}

	public void turnAssignement() {
		if (isHeroeTurn) {
			this.heroTurn();
		} else {
			this.monsterTurn();
		}
		changeIsHeroTurn();
	}

	public String finishedBattle() {
		String finished = "";
		if (playerDefeated()) {
			finished += "The monster: " + getMonster().getName()
					+ " killed all your heroes\n"+
					"Battle lose";
			
				
			
					
		} else {
			finished += "Your hero: " + getHero().getName()
					+ " slew the monster: " + getMonster().getName()
					+ " , and your alive heroes are: "
					+ getPlayer().listHeroesToString();
		}
		for(SpecialObject equip:hero.getSpecialObjects()){
			equip.stopUsingSpecialHability(this);
		}
		return finished;
	}

	public void setGame(Game game) {
		this.game = game;
	}

	public Game getGame() {
		return game;
	}
	private boolean cancelledBattle;
	public boolean isCancelledBattle(){
		
		return cancelledBattle;
	}
	public void changeCancelledBattle(Boolean canceled){
		cancelledBattle=canceled;
	}
		
}
